package userDao

import (
	"context"
	"dev-assistant-backend/utility/codemsg"
	"strings"
	"time"

	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
)

const CreateTableMysqlSQL = `
CREATE TABLE IF NOT EXISTS user (
    id VARCHAR(36) PRIMARY KEY COMMENT '用户ID',
    name VARCHAR(255) NOT NULL COMMENT '用户名',
    email VARCHAR(255) NOT NULL UNIQUE COMMENT '邮箱',
	phone VARCHAR(255) NULL COMMENT '手机号',
    password VARCHAR(255) NOT NULL COMMENT '密码',
    role INT NOT NULL DEFAULT 0 COMMENT '0: user, 1: admin, 2: super_admin',
    status INT NOT NULL DEFAULT 0 COMMENT '0: normal, 1: banned, 2: deleted',
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	INDEX idx_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
`

const CreateTableSqliteSQL = `
CREATE TABLE IF NOT EXISTS user (
    id TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT NOT NULL UNIQUE,
    phone TEXT,
    password TEXT NOT NULL,
    role INTEGER NOT NULL DEFAULT 0,
    status INTEGER NOT NULL DEFAULT 0,
    created_at DATETIME NOT NULL DEFAULT (datetime('now')),
    updated_at DATETIME NOT NULL DEFAULT (datetime('now'))
)
`

// SQLite索引需要单独创建
const CreateSqliteIndexSQL = `
CREATE INDEX IF NOT EXISTS idx_user_email ON user(email);
`

const RoleUser = 0
const RoleAdmin = 1
const RoleSuperAdmin = 2

const StatusNormal = 0
const StatusBanned = 1
const StatusDeleted = 2

// User 用户实体
type Entity struct {
	Id        string     `orm:"id"`
	Name      string     `orm:"name"`
	Email     string     `orm:"email"`
	Phone     string     `orm:"phone"`
	Password  string     `orm:"password"`
	Role      int        `orm:"role"`
	Status    int        `orm:"status"`
	CreatedAt *time.Time `orm:"created_at,omitempty"`
	UpdatedAt *time.Time `orm:"updated_at,omitempty"`
}

func NewEntity(
	id string,
	name string,
	email string,
	phone string,
	password string,
	role int,
	status int,
) *Entity {
	return &Entity{
		Id:       id,
		Name:     name,
		Email:    email,
		Phone:    phone,
		Password: password,
		Role:     role,
		Status:   status,
	}
}

// Create 创建用户
func Create(ctx context.Context, db gdb.DB, user *Entity) error {
	if user.Id == "" {
		g.Log().Line(true).Warning(ctx, "user id is empty", "user", user)
		return codemsg.UserIdEmptyErr
	}
	if user.Email == "" {
		g.Log().Line(true).Warning(ctx, "user email is empty", "user", user)
		return codemsg.UserEmailEmptyErr
	}
	if user.Password == "" {
		g.Log().Line(true).Warning(ctx, "user password is empty", "user", user)
		return codemsg.UserPasswordEmptyErr
	}
	if user.Name == "" {
		g.Log().Line(true).Warning(ctx, "user name is empty", "user", user)
		return codemsg.UserNameEmptyErr
	}
	if user.Role < 0 || user.Role > 2 {
		g.Log().Line(true).Warning(ctx, "user role is invalid", "user", user)
		return codemsg.UserRoleInvalidErr
	}
	if user.Status < 0 || user.Status > 2 {
		g.Log().Line(true).Warning(ctx, "user status is invalid", "user", user)
		return codemsg.UserStatusInvalidErr
	}
	_, err := db.Model("user").Insert(user)
	if err != nil {
		if strings.Contains(err.Error(), "UNIQUE constraint failed") {
			g.Log().Line(true).Info(ctx, "email already exists", "email", user.Email)
			return codemsg.EmailAlreadyExistsErr
		}
		if strings.Contains(err.Error(), "Duplicate entry") {
			g.Log().Line(true).Info(ctx, "duplicate entry", "email", user.Email)
			return codemsg.DuplicateEntryErr
		}
	}
	g.Log().Line(true).Info(ctx, "create user success", "user", user)
	return err
}

// GetById 根据ID获取用户
func GetById(ctx context.Context, db gdb.DB, id string) (*Entity, error) {
	var user Entity
	err := db.Model(
		"user",
	).Where("id", id).Scan(&user)
	if err != nil {
		if err.Error() == "sql: no rows in result set" {
			g.Log().Line(true).Warning(ctx, "user not found", "id", id)
			return nil, codemsg.UserNotFoundErr
		}
		return nil, codemsg.InternalServerErr
	}

	return &user, nil
}

// GetByEmail 根据邮箱获取用户
func GetByEmail(ctx context.Context, db gdb.DB, email string) (*Entity, error) {
	var user Entity
	err := db.Model(
		"user",
	).Where("email", email).Scan(&user)
	if err != nil {
		if err.Error() == "sql: no rows in result set" {
			g.Log().Line(true).Warning(ctx, "user not found", "email", email)
			return nil, codemsg.UserNotFoundErr
		}
		return nil, codemsg.InternalServerErr
	}
	return &user, nil
}

// Delete 删除用户
func Delete(ctx context.Context, db gdb.DB, id string) error {
	if id == "" {
		g.Log().Line(true).Warning(ctx, "user id is empty", "id", id)
		return nil
	}

	_, err := db.Model("user").Where("id", id).Delete()
	if err != nil {
		g.Log().Line(true).Error(ctx, "delete user error", "id", id, "error", err)
		return codemsg.InternalServerErr
	}
	return nil
}
